package com.terra.ns.imp.common.mybatis.mapper

import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper
import toLocalDateTimeEndOfDay
import toLocalDateTimeStartOfDay
import java.time.LocalDate
import kotlin.reflect.KProperty

/**
@author qins
@date 2023/5/31
@desc 增强 mybatis plus KtQueryWrapper
增加拼接条件的方法，增加 xxxIfPresent 方法，用于判断值不存在的时候，不要拼接到条件中。
 使用Kotlin时可以使用lambda表达式
 */
class KtQueryWrapperX<T : Any>(entityClass: Class<T>) : KtQueryWrapper<T>(entityClass) {

    /**
     * 如果有值，就拼上like
     */
    fun likeIfPresent(column: KProperty<*>, value: String?): KtQueryWrapperX<T> {
        return if (value.isNullOrEmpty()) {
            this
        } else {
            like(column, value) as KtQueryWrapperX
        }
    }

    /**
     * 如果有值，就拼上in
     */
    fun inIfPresent(column: KProperty<*>, values: Collection<*>?): KtQueryWrapperX<T> {
        return if (values.isNullOrEmpty()) {
            this
        } else {
            `in`(column, values) as KtQueryWrapperX
        }
    }

    /**
     * 如果有值，就拼上eq
     */
    fun eqIfPresent(column: KProperty<*>, value: Any?): KtQueryWrapperX<T> {
        return if (value == null) {
            this
        } else {
            eq(column, value) as KtQueryWrapperX
        }
    }

    /**
     * 如果有值，就拼上ne
     */
    fun neIfPresent(column: KProperty<*>, value: Any?): KtQueryWrapperX<T> {
        return if (value == null) {
            this
        } else {
            ne(column, value) as KtQueryWrapperX
        }
    }

    /**
     * 如果有值，就拼上gt
     */
    fun gtIfPresent(column: KProperty<*>, value: Any?): KtQueryWrapperX<T> {
        return if (value == null) {
            this
        } else {
            gt(column, value) as KtQueryWrapperX
        }
    }

    /**
     * 如果有值，就拼上ge 大于等于
     */
    fun geIfPresent(column: KProperty<*>, value: Any?): KtQueryWrapperX<T> {
        return if (value == null) {
            this
        } else {
            ge(column, value) as KtQueryWrapperX
        }
    }

    /**
     * 如果有值，就拼上lt
     */
    fun ltIfPresent(column: KProperty<*>, value: Any?): KtQueryWrapperX<T> {
        return if (value == null) {
            this
        } else {
            lt(column, value) as KtQueryWrapperX
        }
    }

    /**
     * 如果有值，就拼上le 小于等于
     */
    fun leIfPresent(column: KProperty<*>, value: Any?): KtQueryWrapperX<T> {
        return if (value == null) {
            this
        } else {
            le(column, value) as KtQueryWrapperX
        }
    }

    /**
     * 如果有值，就拼上between
     */
    fun betweenIfPresent(column: KProperty<*>, value1: Any?, value2: Any?): KtQueryWrapperX<T> {
        if (value1 != null && value2 != null) {
            return between(column, value1, value2) as KtQueryWrapperX
        }
        if (value1 != null) {
            return ge(column, value1) as KtQueryWrapperX
        }
        if (value2 != null) {
            return le(column, value1) as KtQueryWrapperX
        }
        return this
    }

    /**
     * 如果有值，就拼上add
     */
    fun andIfPresent(value: String?, func: (KtQueryWrapper<T>) -> Unit): KtQueryWrapperX<T> {
        if(!value.isNullOrEmpty()) {
            return and(true, func) as KtQueryWrapperX
        }
        return this
    }

    /**
     * 如果有值，就拼上or
     */
    fun orIfPresent(value: String?, func: (KtQueryWrapper<T>) -> Unit): KtQueryWrapperX<T> {
        if(!value.isNullOrEmpty()) {
            return or(true, func) as KtQueryWrapperX
        }
        return this
    }

    // 重写父类  返回KtQueryWrapperX 进行链式调用 --------
    // 添加方法方便链式调用
    /**
     * 只返回一条
     */
    fun lastLimit1(): KtQueryWrapperX<T> {
        return last("limit 1") as KtQueryWrapperX
    }


    /**
     * 根据字段逆序
     */
    fun orderByDescX(column: KProperty<*>): KtQueryWrapperX<T> {
        return orderByDesc(column) as KtQueryWrapperX
    }

    /**
     * 根据字段增序
     */
    fun orderByAscX(column: KProperty<*>): KtQueryWrapperX<T> {
        return orderByAsc(column) as KtQueryWrapperX
    }

    /**
     * 字段相等
     */
    fun eqX(column: KProperty<*>, value : Any?): KtQueryWrapperX<T> {
        return eq(column, value) as KtQueryWrapperX<T>
    }

    /**
     * 字段大于
     */
    fun gtX(column: KProperty<*>, value : Any?): KtQueryWrapperX<T> {
        return gt(column, value) as KtQueryWrapperX<T>
    }

    /**
     * 字段大于等于
     */
    fun geX(column: KProperty<*>, value : Any?): KtQueryWrapperX<T> {
        return ge(column, value) as KtQueryWrapperX<T>
    }

    /**
     * 字段小于
     */
    fun ltX(column: KProperty<*>, value : Any?): KtQueryWrapperX<T> {
        return lt(column, value) as KtQueryWrapperX<T>
    }

    /**
     * 字段相小于等于
     */
    fun leX(column: KProperty<*>, value : Any?): KtQueryWrapperX<T> {
        return le(column, value) as KtQueryWrapperX<T>
    }

    /**
     * 字段不等于
     */
    fun neX(column: KProperty<*>, value : Any?): KtQueryWrapperX<T> {
        return ne(column, value) as KtQueryWrapperX<T>
    }

    /**
     * 字段in
     */
    fun inX(column: KProperty<*>, values: Collection<*>): KtQueryWrapperX<T> {
        return `in`(column, values) as KtQueryWrapperX
    }

    /**
     * 创建时间是今天的条件
     */
    fun inToday(column: KProperty<*>): KtQueryWrapperX<T> {
        return ge(column, LocalDate.now().toLocalDateTimeStartOfDay())
            .le(column, LocalDate.now().toLocalDateTimeEndOfDay()) as KtQueryWrapperX<T>

    }
}